/*
    This file is part of Posixcpp library.

    Posixcpp library is free software: you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public License
    as published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Posixcpp library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU LesserGeneral Public
    License along with Posixcpp library. If not, see
    <http://www.gnu.org/licenses/>.
 */

#ifndef FLAGS_HPP_INCLUDED
#define FLAGS_HPP_INCLUDED

namespace posixcpp {

template<typename EnumClass_t, typename OrdinarType_t>
class Flags {
public:
    
    Flags () : m_data(OrdinarType_t(0)) {
    }

    Flags(OrdinarType_t data) : m_data(data) {
    }
    
    Flags(EnumClass_t data) : m_data(OrdinarType_t(data)) {
        
    }

    void setFlag(EnumClass_t flag)
    {
        m_data |= OrdinarType_t(flag);
    }

    void unsetFlag(EnumClass_t flag)
    {
        m_data &= ~OrdinarType_t(flag);
    }

    void toogleFlag(EnumClass_t flag)
    {
        m_data ^= OrdinarType_t(flag);
    }

    bool testFlag(EnumClass_t flag) const
    {
        return m_data & OrdinarType_t(flag);
    }

    OrdinarType_t data() const
    {
        return m_data;
    }

    OrdinarType_t & data()
    {
        return m_data;
    }
private:
    OrdinarType_t m_data;
};

/**
 * @param FlagsType name of the Flgas type
 * @param FlagType name of the enumeration of the possible flags
 * @param OrdinalType ordinal type for tyhe flags
 */
#define POSIXCPP_FLAGS(FlagsType, FlagType, OrdinalType) \
    enum class FlagType : OrdinalType; \
    typedef posixcpp::Flags<FlagType, OrdinalType> FlagsType; \
    enum class FlagType : OrdinalType

}

#endif // FLAGS_HPP_INCLUDED
